const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const project = require('./aurelia_project/aurelia.json');
const { AureliaPlugin, ModuleDependenciesPlugin } = require('aurelia-webpack-plugin');
const { optimize: { CommonsChunkPlugin }, ProvidePlugin } = require('webpack');

// config helpers:
const ensureArray = (config) => config && (Array.isArray(config) ? config : [config]) || [];
const when = (condition, config, negativeConfig) =>
    condition ? ensureArray(config) : ensureArray(negativeConfig);

// primary config:
const title = 'TMS';
const outDir = path.resolve(__dirname, project.platform.output);
const srcDir = path.resolve(__dirname, 'src');
const nodeModulesDir = path.resolve(__dirname, 'node_modules');
const baseUrl = '/';

const cssRules = [
    { loader: 'css-loader' },
];

module.exports = ({ production, server, extractCss, coverage } = {}) => ({
    resolve: {
        extensions: ['.js'],
        modules: [srcDir, 'node_modules'],
    },
    entry: {
        app: ['aurelia-bootstrapper'],
        vendor: ['bluebird',
            // 'jquery',
            // '@fancyapps/fancybox',
            'autosize',
            'clipboard',
            'clipboard-js',
            'color-hash',
            'dropzone',
            'fullcalendar',
            'highlight.js',
            'isomorphic-fetch',
            'jquery-format',
            'jquery-tablesort',
            'jquery-textcomplete',
            'jquery.hotkeys',
            'jquery.scrollto',
            'lodash',
            'marked',
            'moment',
            'nprogress',
            'push.js',
            'simplemde',
            'timeago.js',
            'tms-semantic-ui',
            'toastr',
            'ua-device',
            'wurl'

            // 'modaal',
            // 'semantic-ui-calendar',
            // 'tinycolorpicker',
        ],
    },
    output: {
        path: outDir,
        // publicPath: baseUrl,
        filename: production ? '[name].[chunkhash].bundle.js' : '[name].[hash].bundle.js',
        sourceMapFilename: production ? '[name].[chunkhash].bundle.map' : '[name].[hash].bundle.map',
        chunkFilename: production ? '[name].[chunkhash].chunk.js' : '[name].[hash].chunk.js'
    },
    externals: {
        jquery: "jQuery"
    },
    devServer: {
        // contentBase: baseUrl,
        // serve index.html for all 404 (required for push-state)
        historyApiFallback: true,
        // publicPath: baseUrl,
        host: 'localhost',
        hot: project.platform.hmr,
        port: project.platform.port,
        open: project.platform.open,
        stats: {
            colors: require('supports-color')
        },
        proxy: [{
            context: ['/free/**', '/admin/**', '/upload/**', '/lib/**'],
            target: 'http://103.36.173.183:9090',
            changeOrigin: true,
            secure: false
        }]
    },
    module: {
        rules: [
            // CSS required in JS/TS files should use the style-loader that auto-injects it into the website
            // only when the issuer is a .js/.ts file, so the loaders are not applied inside html templates
            {
                test: /\.css$/i,
                issuer: [{ not: [{ test: /\.html$/i }] }],
                use: extractCss ? ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: cssRules
                }) : ['style-loader', ...cssRules],
            }, {
                test: /\.css$/i,
                issuer: [{ test: /\.html$/i }],
                // CSS required in templates cannot be extracted safely
                // because Aurelia would try to require it again in runtime
                use: cssRules
            }, {
                test: /\.less$/i,
                use: ['style-loader', 'css-loader', 'less-loader'],
                issuer: /\.[tj]s$/i
            }, {
                test: /\.less$/i,
                use: ['css-loader', 'less-loader'],
                issuer: /\.html?$/i
            },
            { test: /\.html$/i, loader: 'html-loader' }, {
                test: /\.js$/i,
                loader: 'babel-loader',
                exclude: nodeModulesDir,
                options: coverage ? { sourceMap: 'inline', plugins: ['istanbul'] } : {},
            },
            { test: /\.json$/i, loader: 'json-loader' },
            // use Bluebird as the global Promise implementation:
            { test: /[\/\\]node_modules[\/\\]bluebird[\/\\].+\.js$/, loader: 'expose-loader?Promise' },
            // embed small images and fonts as Data Urls and larger ones as files:
            { test: /\.(png|gif|jpg|cur)$/i, loader: 'url-loader', options: { limit: 8192 } },
            { test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff2' } },
            { test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' } },
            // load these fonts normally, as files:
            { test: /\.(ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'file-loader' },
        ]
    },
    plugins: [
        new AureliaPlugin(),
        new ProvidePlugin({
            'Promise': 'bluebird',
            // 'jQuery': "jquery",
            // 'window.jQuery': "jquery",
            // '$': "jquery",
            'moment': 'moment',
            'toastr': 'toastr',
            'timeago': 'timeago.js'
        }),
        new ModuleDependenciesPlugin({
            'aurelia-testing': ['./compile-spy', './view-spy']
        }),
        new HtmlWebpackPlugin({
            template: 'index.ejs',
            minify: production ? {
                removeComments: true,
                collapseWhitespace: true
            } : undefined,
            metadata: {
                // available in index.ejs //
                title,
                server,
                baseUrl
            },
            chunksSortMode: (a, b) => {
                var chunksort = ['vendor', 'app'];
                var aIndex = chunksort.indexOf(a.names[0]);
                var bIndex = chunksort.indexOf(b.names[0]);
                aIndex = aIndex < 0 ? chunksort.length + 1 : aIndex;
                bIndex = bIndex < 0 ? chunksort.length + 1 : bIndex;
                return aIndex - bIndex;
            }
        }),
        ...when(extractCss, new ExtractTextPlugin({
            filename: production ? '[contenthash].css' : '[id].css',
            allChunks: true
        })),
        // ...when(production, new CommonsChunkPlugin({
        //     name: ['common']
        //     // name: ['common', 'boot'],
        // })),
        ...when(production, new CopyWebpackPlugin([
            { from: 'static/favicon.ico', to: 'favicon.ico' },
            { from: 'static/img', to: 'static/img' }
        ]))
    ]
});
